{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 13 生成随机数\n",
    "\n",
    "Numpy.random模块下提供了一些常用的随机函数，可以生成不同概率分布的随机数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.80356311, 0.39336894, 0.43208362],\n",
       "       [0.42206863, 0.03063515, 0.5683432 ],\n",
       "       [0.25142848, 0.86781297, 0.51913174]])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.random.rand(3, 3) # [0,1) 区间的数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = np.random.randint(1, 7, 10000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 4, 2, ..., 5, 5, 6])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "b = np.random.randint(1, 7, 10000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 3, 5, ..., 4, 6, 6])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "c = a + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 2,  7,  7, ...,  9, 11, 12])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([0.03223, 0.05995, 0.0858 , 0.12485, 0.15488, 0.17688, 0.15543,\n",
       "        0.12408, 0.0924 , 0.06512, 0.02838]),\n",
       " array([ 2.        ,  2.90909091,  3.81818182,  4.72727273,  5.63636364,\n",
       "         6.54545455,  7.45454545,  8.36363636,  9.27272727, 10.18181818,\n",
       "        11.09090909, 12.        ]),\n",
       " <a list of 11 Patch objects>)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.hist(c, 11, density=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 14 数组的排序和查找\n",
    "\n",
    "## 14.1 排序\n",
    "\n",
    "numpy的`sort()`函数，它将复制数组并返回排序结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = np.random.randn(4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.25944667, -1.0873003 ,  0.56290138, -1.45977118])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-1.45977118, -1.0873003 ,  0.25944667,  0.56290138])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sort(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果是多维数组，则可以设置axis参数定义需要排序的轴，sort()函数会对这个轴向上的所有元素排序。 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "b = np.random.randn(3, 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.5361825 ,  0.03998547,  0.27339965],\n",
       "       [-0.78238572,  0.23478099, -0.62801061],\n",
       "       [ 0.19589569, -0.72812614,  1.96332753]])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.78238572, -0.72812614, -0.62801061],\n",
       "       [ 0.19589569,  0.03998547,  0.27339965],\n",
       "       [ 0.5361825 ,  0.23478099,  1.96332753]])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sort(b, axis=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`sort()`函数的`order`参数定义排序的关键字段。 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "dtype = [('name', 'U10'), ('height', float), ('weight', int)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "values = [('小明', 170.0, 58), ('小张', 165.0, 60), ('小李', 178.0, 70), ('小王', 170.0, 60)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "c = np.array(values, dtype=dtype)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([('小明', 170., 58), ('小张', 165., 60), ('小李', 178., 70),\n",
       "       ('小王', 170., 60)],\n",
       "      dtype=[('name', '<U10'), ('height', '<f8'), ('weight', '<i8')])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "先按“身高”排序，如果身高一样，则按“体重”排序。 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([('小张', 165., 60), ('小明', 170., 58), ('小王', 170., 60),\n",
       "       ('小李', 178., 70)],\n",
       "      dtype=[('name', '<U10'), ('height', '<f8'), ('weight', '<i8')])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sort(c, order=['height', 'weight'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "数组对象有一个sort()函数，只是它是对数组进行原地排序。 \n",
    "\n",
    "Numpy还提供了间接排序的函数: `lexsort()`，用于返回排序结果的索引值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [5, 1, 4, 2, 8, 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "b = [9, 5, 7, 4, 10, 4]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5, 3, 1, 2, 0, 4])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.lexsort((a, b))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 14.2 查找\n",
    "\n",
    "searchsorted() 是查找数组元素时经常会用到的函数。查找一个合适的位置，将元素插入已排好序的一维数组中，并且保持数组元素的顺序不被打乱。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = np.array([1, 4, 9, 10, 25])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.searchsorted(a, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.searchsorted(a, 9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.searchsorted(a, 26)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([4, 4, 5])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.searchsorted(a, [11, 15, 28])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " searchsorted()函数有个参数side, 默认为left，如果数组有多个位置与查询的数字匹配，返回第一个位置, 如果设置成right，则返回最后一个位置。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = np.array([1, 10, 10, 10, 25])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.searchsorted(a, 10, side='right')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.searchsorted(a, 10, side='left')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`extract()` 函数可以用来提取满足一定条件的元素，比如，提取0, 1, 2..., 16中不能被4整除的数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = np.arange(16).reshape(4, 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0,  1,  2,  3],\n",
       "       [ 4,  5,  6,  7],\n",
       "       [ 8,  9, 10, 11],\n",
       "       [12, 13, 14, 15]])"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "cond = np.mod(a, 4) != 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[False,  True,  True,  True],\n",
       "       [False,  True,  True,  True],\n",
       "       [False,  True,  True,  True],\n",
       "       [False,  True,  True,  True]])"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cond"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 1,  2,  3,  5,  6,  7,  9, 10, 11, 13, 14, 15])"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.extract(cond, a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 15 扩充转换\n",
    "\n",
    "标准的扩充转换（Broadcasting）的目的是，即使各个输入数组形状不完全一样，也能进行运算。\n",
    "\n",
    "- 除纬度最大的输入数组外，其余的所有输入数组的维度向输入数组中最大的数组靠齐，并把那个维度考虑为1。\n",
    "- 输出数组在各个维度上的长度和所有输入数组在那个维度上的最大长度一样。\n",
    "- 如果输入数组在某个维度上的长度为1，或者和输出数组在那个维度上的长度一样，则会被用于实际的计算过程。\n",
    "- 如果输入数组在某个维度上的长度为1，name那个维度上的数组的第一个元素会被用于后续在该维度上的计算。\n",
    "\n",
    "最简单的就是一个数组和一个纯数之间的运算："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 10\n",
    "b = np.arange(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0, 10, 20, 30, 40])"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a*b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "数组间的加法1 (行扩充)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = np.arange(12).reshape(4, 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "b = np.arange(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0,  1,  2],\n",
       "       [ 3,  4,  5],\n",
       "       [ 6,  7,  8],\n",
       "       [ 9, 10, 11]])"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1, 2])"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0,  2,  4],\n",
       "       [ 3,  5,  7],\n",
       "       [ 6,  8, 10],\n",
       "       [ 9, 11, 13]])"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a + b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "数组间的加法1 (列扩充) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [],
   "source": [
    "b = np.arange(4).reshape(4, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0],\n",
       "       [1],\n",
       "       [2],\n",
       "       [3]])"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0,  1,  2],\n",
       "       [ 4,  5,  6],\n",
       "       [ 8,  9, 10],\n",
       "       [12, 13, 14]])"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a + b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "三维甚至更高维度的数组扩充更加复杂。 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
